﻿using JetBrains.Annotations;
using JetBrains.Application;
using JetBrains.ReSharper.Feature.Services.CSharp.Bulbs;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.Util;

namespace MugenMvvmToolkit.ReSharper.Infrastructure
{
    public abstract class PropertyContextAction : ContextActionBaseExt
    {
        #region Constructors

        protected PropertyContextAction([NotNull] ICSharpContextActionDataProvider provider)
            : base(provider)
        {
        }

        #endregion

        #region Properties

        protected IClassDeclaration ClassDeclaration { get; private set; }

        protected IPropertyDeclaration PropertyDeclaration { get; private set; }

        #endregion

        #region Overrides of ContextActionBase

        /// <summary>
        ///     Check if this action is available at the constructed context.
        ///     Actions could store precalculated info in <paramref name="cache" /> to share it between different actions
        /// </summary>
        /// <returns>
        ///     true if this bulb action is available, false otherwise.
        /// </returns>
        public override sealed bool IsAvailable(IUserDataHolder cache)
        {
            using (ReadLockCookie.Create())
            {
                ITreeNode selectedElement = Provider.SelectedElement;
                if (selectedElement == null)
                    return false;
                PropertyDeclaration = selectedElement.Parent as IPropertyDeclaration;
                if (PropertyDeclaration == null || PropertyDeclaration.Parent == null)
                    return false;
                ClassDeclaration = PropertyDeclaration.Parent.Parent as IClassDeclaration;
            }
            return ClassDeclaration != null && IsAvailableInternal(cache);
        }

        #endregion

        #region Methods

        /// <summary>
        ///     Check if this action is available at the constructed context.
        ///     Actions could store precalculated info in <paramref name="cache" /> to share it between different actions
        /// </summary>
        /// <returns>
        ///     true if this bulb action is available, false otherwise.
        /// </returns>
        protected abstract bool IsAvailableInternal(IUserDataHolder cache);

        #endregion
    }
}